<?
class SessionManager extends ORMManager  implements SessionObjectInterface{
	
	const AUTO_TYPE_CLASSIC = 1;
	const AUTO_TYPE_FAKE	= 2;
	
	public  $cookies_name = 'PSP_ID';
	
	public $clientID = 0;
	
	public $sessionData = null;
	
	public $expiredDays = 365;
	
	public $storageObject;
	
	/**
	 * Куда записывать ключ сессии
	 *
	 * @var string может быть 'cookies', 'mail'
	 */
	public $storage;
	
	function __construct($storage = 'cookies') {
		parent::__construct();
		global $options;

		$this->setStorageType($storage);
	}
	
	public function setStorageType($storage){
		$this->storage = $storage;
		switch ($this->storage) {
			case 'cookies':
			break; 
			case 'object':
				$this->storageObject = new stdClass();
			break; 
		}
	}
	
	/**
	 * Добаляет запись для autologin в сессию
	 *
	 */ 
	function addKey($sessionData='') {
		$this->sessionData = $sessionData;
		if (!$this->clientID){
			$this->clientID = Ria_Client::getInstance()->Client->getClientId();
		}
		$this->s_key = $this->_generateKey();
		if ($this->clientID) {
			$this->_addKey();
			$this->_writeKey();
			return true;
		} else {
			return false;
		}
		#if ($this->remember_me) {}
	}
	
	function checkKey() {
		$this->_parse_cookies();
		
		if ($this->ClientIDFake == 0 || $this->s_key == '') {
			return false;
		}
		$data = $this->getQuery()->from('Passport_SessionDBO')->where("sessionKey = '".$this->s_key."' and clientID = ".$this->ClientIDFake)->fetchOne();
		if (is_object($data)) {
			$flag = self::AUTO_TYPE_CLASSIC;
			$client_id = $data->clientID;
			$fake_id = Ria_Client::getInstance()->Client->checkFakeUser($data->fake_id);
			if ($fake_id){
				$flag = self::AUTO_TYPE_FAKE;
				$client_id = $fake_id;
			}
			Ria_Client::getInstance()->Client->loginById($client_id);
			return $client_id;
		} else {
			return false;
		}
	}
	
	function sessionClose() {
		$this->_parse_cookies();
		$this->getQuery()->delete()->from('Passport_SessionDBO')->where("sessionKey = '".$this->s_key."' and clientID = ".$this->ClientIDFake)->execute();
		$this->_removeKey();
	}
	
	/**
	 * Ищет ключ с максимальным expired 
	 *
	 * @return boolean
	 */
	function findActualKey($actual_days=1){
		$session_key = $this->getQuery()->select('sessionKey')->from('Passport_SessionDBO')->where("clientID=$this->clientID and expiredDate>(now() + interval $actual_days day)")->orderBy('expiredDate desc')->limit(1)->fetchOne()->toArray();
		$key = $session_key['sessionKey']; 
		if ($key) {
			$this->s_key=$key;
			$this->_writeKey();
			return true;
		}
		return false;
	}
	
	/**
	 * Генерирует 64-бытный ключ
	 *
	 */ 
	private function _generateKey() {
		return md5(rand()).md5(time()+rand());
	}
	
	
	
	private function _addKey() {
		try {
			$session = new Passport_SessionDBO();
			$session->sessionKey=$this->s_key;
			$session->clientID=$this->clientID;
			$session->sessionData=$this->sessionData;
			$ip_addr = REMOTE_ADDR; 
			if (!$ip_addr) $ip_addr = 0;
			$session->userIP=$ip_addr;
			$session->loginDate=time();
			$session->expiredDate=time()+$this->expiredDays*24*60*60;
			$session->save();
		}catch (Doctrine_Validator_Exception  $e){
				$userErrors = $e->getInvalidRecords();
				foreach ($userErrors as $item){
					$other_stack = $item->getErrorStack();
					foreach( $other_stack as $field => $errors )
					{
						//print "$field";
					}
					
				}
			}
	}
	
	private function _parse_cookies() {
		$key = $this->_readKey();
		$this->s_key = substr($key,0,64);
		$this->ClientIDFake = substr($key,64)*1;
	}
	
	private function _writeKey() {
		$key = $this->s_key.$this->clientID;
		$expired_date = time()+60*60*24*$this->expiredDays;
		switch ($this->storage) {
			case 'cookies':
				setcookie($this->cookies_name,$key,$expired_date);
			break; 
			case 'object':
				$this->storageObject->key = $key;
				$this->storageObject->key_expired = $expired_date;
			break; 
			
		}
	}

	private function _readKey() {
		switch ($this->storage) {
			case 'cookies':
				return $_COOKIE[$this->cookies_name];
			break; 
			case 'object':
				return $this->storageObject->key;
			break; 			
		}
	}

	private function _removeKey() {
		switch ($this->storage) {
			case 'cookies':
				setcookie($this->cookies_name,'',time());
			break; 
			case 'object':
				$this->storageObject->key = null;
				$this->storageObject->key_expired = time();
			break; 			
		}
	}
	
  	public function getObjectState(){
  		return '';
  	}
  
  	public function setObjectState($objectState){
  		
  	}
	
}
?>